package com.cssy.xxkj.logic.service.impl;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
import com.byd.acegiext.domain.User;
import com.cssy.xxkj.logic.contants.BillStatusUtil;
import com.cssy.xxkj.logic.contants.BillTypeConstant;
import com.cssy.xxkj.logic.dao.LogicAllocationDAO;
import com.cssy.xxkj.logic.dao.LogicAllocationItemDAO;
import com.cssy.xxkj.logic.dao.LogicWarehouseInventoryDAO;
import com.cssy.xxkj.logic.entity.LogicAllocationDO;
import com.cssy.xxkj.logic.entity.LogicAllocationItemDO;
import com.cssy.xxkj.logic.entity.vo.LogicWarehouseInventoryVO;
import com.cssy.xxkj.logic.service.ILogicAllocationService;
import com.cssy.xxkj.logic.service.ILogicHsUtilService;
import com.plat.exception.SyBaseException;
import com.plat.helper.SearchCondition;
import com.plat.helper.SearchConditions;
import com.plat.helper.SearchResult;
import com.plat.util.DateUtils;
import com.plat.util.GlobalResLoader;
import com.plat.util.IDCodeTypeUtil;
import com.plat.util.SessionUtil;
import com.yuendong.sy.po.code.SyCode;
import com.yuendong.sy.service.code.impl.SyCodeService;

@Service("logicAllocationService")
public class LogicAllocationServiceImpl implements ILogicAllocationService {

	@Resource(name = "logicAllocationDAO")
	private LogicAllocationDAO logicAllocationDAO;
	
	@Resource(name = "logicAllocationItemDAO")
	private LogicAllocationItemDAO logicAllocationItemDAO;
	
	@Resource(name = "logicWarehouseInventoryDAO")
	private LogicWarehouseInventoryDAO logicWarehouseInventoryDAO;
	
	@Resource(name = "logicHsUtilService")
	private ILogicHsUtilService logicHsUtilService;
	
	@Resource(name = "syCodeService")
	private SyCodeService syCodeService;
	
	@Override
	public SearchResult findListByExample(SearchConditions scs)
			throws SyBaseException {
		SearchResult rs = new SearchResult(scs);
		List<LogicAllocationDO> list = logicAllocationDAO.find(scs);
		rs.setRecordCount(logicAllocationDAO.count(scs));
		rs.setResults(list);
		return rs;
	}
	
	@Override
	public List<LogicAllocationItemDO> findItemListByMap(Map<String, Object> paramMap)
		throws SyBaseException{
		return logicAllocationItemDAO.findListByMap(paramMap);
	}

	@Override
	public Integer delete(String id, User user) throws SyBaseException {
		return logicAllocationDAO.deleteLogicAllocationDOByPrimaryKey(id);
	}

	@Override
	public Integer update(LogicAllocationDO act, User user)
			throws SyBaseException {
		act.setBizModifyName(user.getName());
		act.setBizModifyDate(new Date());
		act.setBizVersionMark(act.getBizVersion());
		act.setBizVersion(act.getBizVersion()+Integer.valueOf(1));
		return logicAllocationDAO.updateLogicAllocationDO(act);
	}

	@Override
	public LogicAllocationDO save(LogicAllocationDO act, User user)
			throws SyBaseException {
		act.setBizVersion(Integer.valueOf(1));
		act.setBizCreatorName(user.getName());
		act.setBizCreatorDate(new Date());
		logicAllocationDAO.insertLogicAllocationDO(act);
		return act;
	}
	
	@Override
	public void allocationSave(HttpServletRequest request, LogicAllocationDO curAP)
			throws SyBaseException{
		try{
			String flagMark = request.getParameter("flagMark");
			String dataitem = request.getParameter("dataitem");
			String dataitemdel = request.getParameter("dataitemdel");
			String zd005OutDate = request.getParameter("zd005OutDate");
			if(StringUtils.isNotBlank(zd005OutDate)){
				curAP.setZd005OutDate(DateUtils.stringToDate(zd005OutDate));
			}
			String zd005InDate = request.getParameter("zd005InDate");
			if(StringUtils.isNotBlank(zd005InDate)){
				curAP.setZd005InDate(DateUtils.stringToDate(zd005InDate));
			}
			curAP.setZd002Status(flagMark);
			List<LogicAllocationItemDO> actItemList = JSON.parseArray(dataitem, LogicAllocationItemDO.class);
			if(curAP==null || StringUtils.isBlank(curAP.getId())){
				//新增
				String actId = IDCodeTypeUtil.getId();
				curAP.setId(actId);
				String actCode = syCodeService.getCode(BillTypeConstant.ALLOCATION,BillTypeConstant.ALLOCATION,SyCode.DATE_YYMM,5);
				curAP.setZd001Code(actCode);
				this.save(curAP, SessionUtil.getUser(request));
				//新增行记录
				for(LogicAllocationItemDO actItem : actItemList){
					if(actItem==null){
						continue;
					}
					actItem.setZd001AllocationId(actId);
					actItem.setZd001AllocationCode(actCode);
					actItem.setId(IDCodeTypeUtil.getId());
					logicAllocationItemDAO.insertLogicAllocationItemDO(actItem);
				}
			}else{
				//修改
				String actId = curAP.getId();
				Integer rowUp = this.update(curAP, SessionUtil.getUser(request));
				if(rowUp.intValue()==0){
					throw new SyBaseException("");
				}else{
					//删除
					if(StringUtils.isNotBlank(dataitemdel)){
						List<LogicAllocationItemDO> actItemListToDel = JSON.parseArray(dataitemdel, LogicAllocationItemDO.class);
						for(LogicAllocationItemDO actItem : actItemListToDel){
							if(actItem==null || StringUtils.isBlank(actItem.getId())){
								continue;
							}
							logicAllocationItemDAO.deleteLogicAllocationItemDOByPrimaryKey(actItem.getId());
						}
					}
					//修改行记录
					for(LogicAllocationItemDO actItem : actItemList){
						if(actItem==null){
							continue;
						}
						if(StringUtils.isBlank(actItem.getId())){
							actItem.setZd001AllocationId(actId);
							actItem.setZd001AllocationCode(curAP.getId());
							actItem.setId(IDCodeTypeUtil.getId());
							logicAllocationItemDAO.insertLogicAllocationItemDO(actItem);
						}else{
							logicAllocationItemDAO.updateLogicAllocationItemDO(actItem);
						}
					}
				}
				//判断是否审核通过
				if(BillStatusUtil.ACT_BILL_STATUS_ZTWO.equals(flagMark)){
					Map<String, BigDecimal> materQuanMap = findQueryMaterQuantityToMap(curAP.getZd003OutWhCode());
					int numRow = 0;
					for(LogicAllocationItemDO actItem : actItemList){
						numRow++;
						if(actItem==null||StringUtils.isBlank(actItem.getId())){
							continue;
						}
						String keyStr = curAP.getZd003OutWhCode()+"_"+actItem.getZd002MaterId()+"_"
									+actItem.getZd007Model()+"_"+actItem.getZd006Spec()+"_"
									+actItem.getZd009Color()+"_"+actItem.getZd010Quality();
						BigDecimal outQuantity = actItem.getZd019Quantity()==null?BigDecimal.ZERO:actItem.getZd019Quantity();
						if(materQuanMap==null||materQuanMap.get(keyStr)==null){
							throw new SyBaseException("错误：第"+numRow+"的物料没有库存不能进行调拨。");
						}else{
							BigDecimal kcQuantity = materQuanMap.get(keyStr);
							BigDecimal compQuantity = kcQuantity.subtract(outQuantity);
							if(BigDecimal.ZERO.compareTo(compQuantity)==1){
								throw new SyBaseException("错误：第"+numRow+"物料调拨数量大于库存数量。");
							}
							//改变库存
							logicHsUtilService.processHsAllocationItem(curAP, actItem, SessionUtil.getUser(request));
						}
					}
				}
			}
		}catch(Exception e){
			e.printStackTrace();
			throw new SyBaseException(GlobalResLoader.getOpfailed()+ e.getMessage());
		}
	}
	
	private Map<String, BigDecimal> findQueryMaterQuantityToMap(String whCode){
		SearchConditions whScs = new SearchConditions();
		whScs.setRemovedProperty(null);
		whScs.addCondition("logic_warehouse_inventory.zd001WhCode", whCode, SearchCondition.OP_EQUAL);
		List<LogicWarehouseInventoryVO>  whList =logicWarehouseInventoryDAO.findForWareHouseStock(whScs);
		if(whList==null||whList.isEmpty()||whList.size()==0){
			return null;
		}else{
			Map<String, BigDecimal> whMap = new HashMap<String, BigDecimal>();
			for(LogicWarehouseInventoryVO wh : whList){
				if(wh==null||StringUtils.isBlank(wh.getId())){
					continue;
				}
				String keyStr = whCode + "_" + wh.getZd003MaterialsId()+"_"+wh.getZd007MaterialsModel()+"_"
					+wh.getZd006MaterialsSpec()+"_"+wh.getZd008MaterialsColor()+"_"+wh.getZd008MaterialsQuanlity();
				BigDecimal zdQuantity = wh.getZd009Quantity()==null?BigDecimal.ZERO:wh.getZd009Quantity();
				if(whMap.get(keyStr)==null){
					whMap.put(keyStr, zdQuantity);
				}else{
					whMap.put(keyStr, zdQuantity.add(whMap.get(keyStr)));
				}
			}
			return whMap;
		}
			
			
	}

	@Override
	public LogicAllocationDO findListById(String id) throws SyBaseException {
		return logicAllocationDAO.findLogicAllocationDOByPrimaryKey(id);
	}

	@Override
	public Integer deleteBizRemoved(String id) throws SyBaseException {
		return logicAllocationDAO.deleteBizRemoved(id);
	}

}
